package MuleBackend;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 * The town class holds the logic needed
 * to interact with the town and its stalls
 * @author Jackson
 *
 */
public class Town
{

	private static int crystiteStock = 0;
	private static int muleStock;
	private static int smithoreStock;
	private static int foodStock;
	private static int energyStock;
	private int BASE_MULE_COST = 100;
	
	private int maxFoodPrice = 100;
	private int maxEnergyPrice = 100;
	private int maxSmithorePrice = 100;
	private int maxCrystitePrice;
	
	private int currentFoodPrice;
	private int currentEnergyPrice;
	private int currentSmithorePrice;
	private int currentCrystitePrice;
	
	private int minFoodPrice = 25;
	private int minEnergyPrice = 25;
	private int minSmithorePrice = 25;
	private int minCrystitePrice;
	
	public static final int FOOD_FIT_PRICE=10;
	public static final int ENERGY_FIT_PRICE=25;
	public static final int SMITHORE_FIT_PRICE=50;
	public static final int CRYSTITE_FIT_PRICE=100;
	public static int BASE_MULE_PRICE=100;
	public static int MULE_PRICE=100;
	
	/**
	 * constructor for the town class
	 * that will hold the necessary information needed
	 */
	public Town(){
		muleStock = 10;
		smithoreStock = 0;
		foodStock = 10;
		energyStock = 10;
		
		currentFoodPrice = 50;
		currentSmithorePrice = 50;
		currentEnergyPrice = 50;
	}

	
	/**
	 * getter method to get the crystite stock
	 * @return the crystite stock inside the town
	 */
	public static int getCrystiteStock() {
		return crystiteStock;
	}
	
	/**
	 * getter method to get the mule stock
	 * @return the mule stock inside the town
	 */
	public int getMuleStock() {
		return muleStock;
	}
	

	/**
	 * getter method to get the smithore stock
	 * @return the smithore stock inside the town
	 */
	public static int getSmithoreStock() {
		return smithoreStock;
	}
	

	/**
	 * getter method to get the food stock
	 * @return the food stock inside the town
	 */
	public static int getFoodStock(){
		return Town.foodStock;
	}
	
	/**
	 * getter method to get the energy stock
	 * @return the energy stock inside the town
	 */
	public static int getEnergyStock() {
		return energyStock;
	}
	//Store stock setter methods. They take in an amount by which the stock
	//will be incremented/decremented and add/subtract that to the current store stock.

	/**
	 * setter method to add mules to the stock
	 * @param add number of mules to add
	 */
	public void setMuleStock(int add) { 
		muleStock = muleStock+add; 
	}
	
	/**
	 * setter method to add smithore to the stock
	 * @param add number of smithore to add
	 */
	public void setSmithoreStock(int add) {
		smithoreStock = smithoreStock+add;
		Inventory.totalSmithore+=add;
	}
	
	/**
	 * setter method to add energy to the stock
	 * @param add number of energy to add
	 */
	public void setEnergyStock(int add) {
		energyStock = energyStock+add;
		Inventory.totalEnergy+=add;
	}
	
	/**
	 * setter method to add food to the stock
	 * @param add the number of food to add
	 */
	public void setFoodStock(int add) {
		foodStock = foodStock+add;
		Inventory.totalFood+=add;
	}
	
	public static void updateMules()
	{
		if(smithoreStock > 0)
		{
			muleStock += smithoreStock;
			smithoreStock = 0;
		}
	}
	
	
	/**
	 * method to set the cost of the mule
	 * @param cost the cost of the mule
	 * @return
	 */
	public int calculateMuleCost(int cost) {
		int muleCost = cost;		
		return muleCost;
	}
	
	public int getCurrentFoodPrice() {
		return currentFoodPrice;
	}
	
	public int getCurrentEnergyPrice() {
		return currentEnergyPrice;
	}
	
	public int getCurrentSmithorePrice() {
		return currentSmithorePrice;
	}
	
	public void updateFoodPrice(int amount)
	{
		currentFoodPrice += amount;		
		
		if(currentFoodPrice > maxFoodPrice)
			currentFoodPrice = maxFoodPrice;
		
		if(currentFoodPrice < minFoodPrice)
			currentFoodPrice = minFoodPrice;
	}
	
	public void updateEnergyPrice(int amount)
	{
		currentEnergyPrice += amount;	
					
		if(currentEnergyPrice > maxEnergyPrice)
			currentEnergyPrice = maxEnergyPrice;
		
		if(currentEnergyPrice < minEnergyPrice)
			currentEnergyPrice = minEnergyPrice;
	}
	
	public void updateSmithorePrice(int amount)
	{
		currentSmithorePrice += amount;		
		
		if(currentSmithorePrice > maxSmithorePrice)
			currentSmithorePrice = maxSmithorePrice;
		
		if(currentSmithorePrice < minSmithorePrice)
			currentSmithorePrice = minSmithorePrice;
	}
	
	
	/**
	 * logic for the player to purchase a mule
	 * @param active the current player
	 * @param inv an inventory
	 */
	public void buyMule(Player active, Inventory inv) {
		if(active.getInventory().getMule()>=Inventory.PLAIN_MULE){
			JOptionPane.showMessageDialog(new JPanel(), "You already have a mule");
		}else if(active.getInventory().getMoney() < calculateMuleCost(BASE_MULE_PRICE)){
			JOptionPane.showMessageDialog(new JPanel(), "Insufficient funds");
		}else{
			active.deductMoney(calculateMuleCost(BASE_MULE_PRICE));
			active.getInventory().setMule(Inventory.PLAIN_MULE);
		}
					
	}
	
	/**
	 * string representation of the town
	 */
	public String toString() {
		return "I am a Town" + "\n";
	}
	
	public int unitsToSell(int goodType) {
		if(goodType==0) return getFoodStock();
		if(goodType==1) return getEnergyStock();
		if(goodType==2) return getSmithoreStock();
		if(goodType==3) return getCrystiteStock();
		return 0;
	}
	
	public void setPrices(){
		/*
		ArrayList<Player> players = GameDriver.game.getPlayerList();
		int netFood=0, netEnergy=0, netSmithore=0, netCrystite=0;
		for(int k=0;k<players.size();k++){
			netFood += players.get(k).getFood();
			netEnergy += players.get(k).getEnergy();
			netSmithore += players.get(k).getSmithore();
			netCrystite += players.get(k).getCrystite();
		}
		netFood += foodStock;
		netEnergy += energyStock;
		netSmithore += smithoreStock;
		
		if(netFood==0) maxFoodPrice = 250;
		else maxFoodPrice =(int) (200.0 * (players.size()-1) / (netFood));
		if(netEnergy==0) maxEnergyPrice = 250;
		else maxEnergyPrice = (int) (200.0 * (players.size()-1) / (netEnergy));
		if(netSmithore == 0) maxSmithorePrice = 250;
		else maxSmithorePrice =(int) (200.0 * (players.size()-1) / (netSmithore));
		if(netCrystite == 0) maxCrystitePrice = 600;
		else maxCrystitePrice = 400;
		*/
		maxFoodPrice = 30;
		maxEnergyPrice = 30;
		maxSmithorePrice = 30;
		maxCrystitePrice = 300;
		minFoodPrice = 10;
		minEnergyPrice = 10;
		minSmithorePrice = 10;
		minCrystitePrice = 200;
	}
	
	/**
	 * returns the max Price of good (int)
	 * @param goodType int that represents the good
	 * @return the maxPrice of the good
	 */
	public int getMaxPrice(int goodType){
		if(goodType==0)return maxFoodPrice;
		if(goodType==1)return maxEnergyPrice;
		if(goodType==2)return maxSmithorePrice;
		if(goodType==3)return maxCrystitePrice;
		return 0;
	}
	
	/**
	 * returns the min Price of good (int)
	 * @param goodType int that represents the good
	 * @return the minPrice of the good
	 */
	public int getMinPrice(int goodType){
		if(goodType==0)return minFoodPrice;
		if(goodType==1)return minEnergyPrice;
		if(goodType==2)return minSmithorePrice;
		if(goodType==3)return minCrystitePrice;
		return 0;
	}

	/**
	 * deducts 1 unit of good depending on good type
	 * @param goodType
	 */
	public void deductGood(int goodType) {
		if(goodType==0) foodStock-=1;
		if(goodType==1) energyStock-=1;
		if(goodType==2) smithoreStock-=1;
	}
	/**
	 * deducts 1 unit of good depending on good type
	 * @param goodType
	 */
	public void addGood(int goodType) {
		if(goodType==0) foodStock+=1;
		if(goodType==1) energyStock+=1;
		if(goodType==2) smithoreStock+=1;
	}
	/**
	 * Checks if town has enough of the good type to sell
	 * @param goodType
	 * @return
	 */
	public boolean hasGood(int goodType){
		if(goodType==0 && foodStock>0)return true;
		if(goodType==1 && energyStock>0)return true;
		if(goodType==2 && smithoreStock>0)return true;
		return false;
	}
}

